{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Complex Arithmetic Tutorial Workbook\n",
    "\n",
    "**What is this workbook?**\n",
    "A workbook is a collection of problems, accompanied by solutions to them. \n",
    "The explanations focus on the logical steps required to solve a problem; they illustrate the concepts that need to be applied to come up with a solution to the problem, explaining the mathematical steps required. \n",
    "\n",
    "Note that a workbook should not be the primary source of knowledge on the subject matter; it assumes that you've already read a tutorial or a textbook and that you are now seeking to improve your problem-solving skills. You should attempt solving the tasks of the respective kata first, and turn to the workbook only if stuck. While a textbook emphasizes knowledge acquisition, a workbook emphasizes skill acquisition.\n",
    "\n",
    "This workbook describes the solutions to the problems offered in the [Complex Arithmetic tutorial](./ComplexArithmetic.ipynb). \n",
    "Since the tasks are offered as programming problems, the explanations also cover some elements of Python that might be non-obvious for a first-time user.\n",
    "\n",
    "**What you should know for this workbook**\n",
    "\n",
    "1. Basic math.\n",
    "2. Basic Python knowledge is helpful but not necessary."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Click the cell with code below this block of text and press `Ctrl+Enter` (`⌘+Enter` on Mac). **Do not skip this step**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run this cell using Ctrl+Enter (⌘+Enter on Mac).\n",
    "from testing import exercise\n",
    "from typing import Tuple\n",
    "\n",
    "import math\n",
    "\n",
    "Complex = Tuple[float, float]\n",
    "Polar = Tuple[float, float]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 1</span>: Powers of $i$.\n",
    "\n",
    "**Input:** An even integer $n$.\n",
    "\n",
    "**Goal:** Return the $n$th power of $i$, or $i^n$.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "When raising $i$ to an integer power, the answer will vary according to a certain pattern. \n",
    "To figure it out, notice that raising $i$ to the power of 4 gives: $i^4 = i^2 \\cdot i^2 = (-1) \\cdot (-1) = 1$. \n",
    "Thus, when the power $n$ is divisible by 4, $i^n$ will always be 1. \n",
    "\n",
    "When the power $n$ is not divisible by 4, you can use the previous observation to see that $i^n = i^{n \\mod 4}$. \n",
    "For an even power $n$ that is not divisible by 4 you'll have $i^n = i^2 = -1.$\n",
    "\n",
    "Here is the complete pattern that arises when raising $i$ to non-negative powers. Note that it is periodic with period 4.\n",
    "\n",
    "|Power of $i$ | $i^0$ | $i^1$ | $i^2$ | $i^3$ | $i^4$ | $i^5$ | $i^6$ | $i^7$ | $i^8$ | $\\dots$ |\n",
    "|----|----|----|----|----|----|----|----|----|----|----|\n",
    "|Result | $1$ | $i$ | $-1$ | $-i$ | $1$ | $i$ | $-1$ | $-i$ | $1$ | $\\dots$ |\n",
    "\n",
    "> *Python note*:  `%` is the Python modulo operator which returns the remainder of a division. For example, `7%2` gives 1, because 1 is the remainder of dividing 7 by 3.  \n",
    "> We can use this operator to figure out whether the power $n$ is divisible by 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def imaginary_power(n : int) -> int:\n",
    "    # If n is divisible by 4\n",
    "    if n % 4 == 0:\n",
    "        return 1\n",
    "    else:\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 1 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-1:-Powers-of-$i$.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 2</span>: Complex addition.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
    "\n",
    "**Goal:** Return the sum of these two numbers $x + y = z = g + hi$, represented as a tuple `(g, h)`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "Adding two complex numbers can be done by separately adding the real parts of the numbers and the imaginary parts:  \n",
    "\n",
    "$$ z = x + y = (a + bi) + (c + di) = \\underset{real}{\\underbrace{(a + c)}} + \\underset{imaginary}{\\underbrace{(b + d)}}i $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_add(x : Complex, y : Complex) -> Complex:\n",
    "    # You can extract elements from a tuple like this\n",
    "    a = x[0]\n",
    "    b = x[1]\n",
    "    \n",
    "    c = y[0]\n",
    "    d = y[1]\n",
    "    \n",
    "    # This creates a new variable and stores the real component into it\n",
    "    real = a + c\n",
    "    # Replace the ... with code to calculate the imaginary component\n",
    "    imaginary = b + d\n",
    "    \n",
    "    # You can create a tuple like this, with the real and imaginary part of the number\n",
    "    ans = (real, imaginary)\n",
    "    \n",
    "    return ans"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 2 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-2:-Complex-addition.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 3</span>: Complex multiplication.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
    "\n",
    "**Goal:** Return the product of these two numbers $x \\cdot y = z = g + hi$, represented as a tuple `(g, h)`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "Multiplying complex numbers is like multiplying polynomials, therefore the same rules apply. **Remember** $i^2 =-1$.  \n",
    "\n",
    "\n",
    "$$z = x \\cdot y = (a + bi)(c + di) = a \\cdot c + a \\cdot di + c \\cdot bi + bi \\cdot di = \\underset{real}{\\underbrace{a \\cdot c - b \\cdot d}} + \\underset{imaginary}{\\underbrace{(a \\cdot d + c \\cdot b)}}i $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_mult(x : Complex, y : Complex) -> Complex:\n",
    "    \n",
    "    # Here is another, more compact way of extracting the parts of the complex number:\n",
    "    (a, b) = x\n",
    "    (c, d) = y\n",
    "    \n",
    "    real = (a * c) - (b * d)\n",
    "    imaginary = (a * d) + (c * b)\n",
    "    \n",
    "    # Instead of creating a separate tuple with the result, we return the tuple directly\n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 3 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-3:-Complex-multiplication.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 4</span>: Complex conjugate.\n",
    "\n",
    "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "\n",
    "**Goal:** Return $\\overline{x} = g + hi$, the complex conjugate of $x$, represented as a tuple `(g, h)`.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "To get the complex conjugate of a complex number you change the sign of the imaginary part of the complex number:  \n",
    "\n",
    "$$\\overline{x} = a - bi$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def conjugate(x : Complex) -> Complex:\n",
    "    \n",
    "    real = x[0]\n",
    "\n",
    "    # The sign can be easily flipped with the unary minus operator\n",
    "    imaginary = - x[1]\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 4 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-4:-Complex-conjugate.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 5</span>: Complex division.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "2. A complex number $y = c + di \\neq 0$, represented as a tuple `(c, d)`.\n",
    "\n",
    "**Goal:** Return the result of the division $\\frac{x}{y} = \\frac{a + bi}{c + di} = g + hi$, represented as a tuple `(g, h)`.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    " \n",
    "$$z = \\frac{x}{y} = \\frac{x}{y} \\cdot 1 = \\frac{x}{y} \\cdot \\frac{\\overline{y}}{\\overline{y}} = \n",
    "\\frac{x\\overline{y}}{y\\overline{y}} = \\frac{(a + bi)(c - di)}{(c + di)(c - di)} = \n",
    "\\frac{a \\cdot c + bi \\cdot c - a \\cdot di - bi \\cdot di}{c \\cdot c + di \\cdot c - c \\cdot di - di \\cdot di} = \n",
    "\\frac{a \\cdot c + b \\cdot d + (a \\cdot (-d) + c \\cdot b)i}{c^2 + d^2}$$\n",
    "\n",
    "\n",
    "> *Python note*:  In Python you can use an operator `**` to raise a number to the given power; $2^3$ can be written as `x = 2 ** 3`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_div(x : Complex, y : Complex) -> Complex:\n",
    "    \n",
    "    (a, b) = x\n",
    "    (c, d) = y\n",
    "    \n",
    "    # We will use the denominator multiple times, so we'll store the value in a separate variable, \n",
    "    # to make the code easier to use and less error prone.\n",
    "    # Here we use ** to raise c and d to the second power.\n",
    "    denominator = (c ** 2) + (d ** 2)\n",
    "    \n",
    "    real = ((a * c) + (b * d)) / denominator\n",
    "    imaginary = ((a * (-d) ) + (c * b)) / denominator\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 5 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-5:-Complex-division.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 6</span>: Modulus.\n",
    "\n",
    "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "\n",
    "**Goal:** Return the modulus of this number, $|x|$.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "The modulus of the complex number can be seen as the distance from the origin 0 to the $z$ point in the complex plane. This can be calculated using the Pythagorean theorem: $c^2 = a^2 + b^2$, which means $ c = \\sqrt{a^2 + b^2} $.\n",
    "\n",
    "<img src=\"img/pythagorean_theorem.png\" style=\"max-height: 350px;\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> *Python note*: In the `math` library of Python you can use the `sqrt` function to calculate the square root of a number. \n",
    "> To use `math` library, we'd need to first call `import math`, but this is already done for us in the first cell of the notebook.\n",
    "> After that, to use a function from that library, you can simply use `math.(functionName)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def modulus(x : Complex) -> float:\n",
    "    return math.sqrt(x[0] ** 2 + x[1] ** 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 6 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-6:-Modulus.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 7</span>: Complex exponents.\n",
    "\n",
    "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "\n",
    "**Goal:** Return the complex number $e^x = e^{a + bi} = g + hi$, represented as a tuple `(g, h)`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "To start, we will rewrite the expression $e^{a + bi}$ as a product of two simpler expressions: $ e^a \\cdot\\ e^{bi} $.\n",
    "The first part is a real number. \n",
    "The second part can be expressed using the formula $e^{i\\theta} = \\cos \\theta + i\\sin \\theta$.  \n",
    "Substituting this into our expression gives:\n",
    "$$ e^a(\\cos b + i\\sin b) = \\underset{real}{\\underbrace{e^a \\cos b}} + \\underset{imaginary}{\\underbrace{e^a \\sin b}}i  $$\n",
    "\n",
    "> *Python note:* Python `math` library offers multiple trigonometric functions, including `cos` and `sin`, and constants, including Euler's constant $e$ (accessed as `math.e`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_exp(x : Complex) -> Complex:\n",
    "    \n",
    "    (a, b) = x\n",
    "    \n",
    "    expa = math.e ** a\n",
    "    \n",
    "    real = expa * math.cos(b)\n",
    "    imaginary = expa * math.sin(b)\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 7 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-7:-Complex-exponents.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 8</span>*: Complex powers of real numbers.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A non-negative real number $r$.\n",
    "2. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "\n",
    "**Goal:** Return the complex number $r^x = r^{a + bi} = g + hi$, represented as a tuple `(g, h)`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "Let's rewrite the expression $r^x$ to use Euler's constant, which will allow us to use an approach similar to the solution to the previous exercise.\n",
    "\n",
    "First, we rewrite $r^x$ into a product of two powers: $$ r^{a+bi} = r^a \\cdot r^{bi} $$\n",
    "\n",
    "Given that $r = e^{\\ln r} $ ($\\ln$ is the natural logarithm), we can rewrite the second part of the product as follows: \n",
    "$$ r^{bi} =  e^{bi\\ln r} $$\n",
    "\n",
    "Now, given $e^{i\\theta} = \\cos \\theta + i\\sin \\theta$, we can rewrite it further as follows: \n",
    "$$ e^{bi\\ln r} = \\cos( b \\cdot \\ln r) + i \\sin(b \\cdot \\ln r) $$\n",
    "\n",
    "When substituting this into our original expression, we get:  \n",
    "$$ \\underset{real}{\\underbrace{r^a \\cos(b \\cdot \\ln r)}} + \\underset{imaginary}{\\underbrace{r^a \\sin(b \\cdot \\ln r)}} i $$ \n",
    "\n",
    "> *Python note*: To get the natural logarithm in Python, you can use the `log` function from the `math` library.  \n",
    "> You can perform basic conditional operations based on Boolean conditions with the `if` statement. \n",
    "> The syntax can be seen in the code below, you can also add `else` or `elif` statements which are described [here](https://www.w3schools.com/python/python_conditions.asp). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_exp_real(r : float, x : Complex) -> Complex:\n",
    "    \n",
    "    # Since ln(r) is only defined for positive numbers, we check for this special case.\n",
    "    # If r = 0, raising it to any power will give 0.\n",
    "    # Calling return before the end of the function will not execute the rest of the function.\n",
    "    if (r == 0):\n",
    "        return (0,0)\n",
    "    \n",
    "    (a, b) = x\n",
    "    \n",
    "    # Raise r to the power of a\n",
    "    ra = r ** a\n",
    "    \n",
    "    # Natural logarithm of r\n",
    "    lnr = math.log(r)\n",
    "    \n",
    "    real = ra * math.cos(b * lnr)\n",
    "    imaginary = ra * math.sin(b * lnr)\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 8 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-8*:-Complex-powers-of-real-numbers.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 9</span>: Cartesian to polar conversion.\n",
    "\n",
    "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "\n",
    "**Goal:** Return the polar representation of $x = re^{i\\theta}$, i.e., the distance from origin $r$ and phase $\\theta$ as a tuple `(r, θ)`.\n",
    "\n",
    "* $r$ should be non-negative: $r \\geq 0$\n",
    "* $\\theta$ should be between $-\\pi$ and $\\pi$: $-\\pi < \\theta \\leq \\pi$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "We need to calculate the $r$ and $\\theta$ values as seen in the complex plane. \n",
    "$r$ should be familiar to you already, since it is the modulus of a number (exercise 6):\n",
    "\n",
    "$$ r = \\sqrt{a^2 + b^2} $$\n",
    "\n",
    "$\\theta$ can be calculated using trigonometry: since we know that the polar and the Cartesian forms of the number represent the same value, we can write\n",
    "\n",
    "$$ re^{i \\theta} = a + bi $$\n",
    "\n",
    "Euler's formula allows us to express the left part of the equation as \n",
    "\n",
    "$$ re^{i \\theta} = r \\cos \\theta + i r \\sin \\theta $$\n",
    "\n",
    "For two complex numbers to be equal, their real and imaginary parts have to be equal. This gives us the following system of equations:\n",
    "\n",
    "$$ \\begin{cases} a = r \\cos \\theta \\\\ b = r \\sin \\theta \\end{cases} $$\n",
    "\n",
    "To calculate $\\theta$, we can divide the second equation by the first one to get\n",
    "\n",
    "$$ \\tan \\theta = \\frac{b}{a} $$\n",
    "\n",
    "$$ \\theta = \\arctan \\left(\\frac{b}{a}\\right) $$\n",
    "\n",
    "> *Python note:* The `arctan2(b, a)` function from the `math` library returns `atan(b / a)` in radians. It will also handle the special case of $a = 0$ gracefully."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def polar_convert(x : Complex) -> Polar:\n",
    "    \n",
    "    (a, b) = x\n",
    "    \n",
    "    r = math.sqrt(a**2 + b **2)\n",
    "    theta = math.atan2(b, a)\n",
    "    \n",
    "    return (r, theta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 9 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-9:-Cartesian-to-polar-conversion.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 10</span>: Polar to Cartesian conversion.\n",
    "\n",
    "**Input:** A complex number $x = re^{i\\theta}$, represented in polar form as a tuple `(r, θ)`.\n",
    "\n",
    "**Goal:** Return the Cartesian representation of $x = a + bi$, represented as a tuple `(a, b)`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"img/Polar_to_Cartesian.png\" style=\"max-height:350px;\">\n",
    "\n",
    "Using the trigonometric functions of the right triangle, you can get the following expressions (which you've obtained algebraically in the previous exercise):\n",
    "\n",
    "$$ \\begin{cases} a = r \\cos \\theta \\\\ b = r \\sin \\theta \\end{cases} $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def cartesian_convert(x : Polar) -> Complex:\n",
    "    \n",
    "    (r, theta) = x\n",
    "    \n",
    "    real = r * math.cos(theta)\n",
    "    imaginary = r * math.sin(theta)\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 10 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-10:-Polar-to-Cartesian-conversion.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 11</span>: Polar multiplication.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A complex number $x = r_{1}e^{i\\theta_1}$ represented in polar form as a tuple `(r1, θ1)`.\n",
    "2. A complex number $y = r_{2}e^{i\\theta_2}$ represented in polar form as a tuple `(r2, θ2)`.\n",
    "\n",
    "**Goal:** Return the result of the multiplication $x \\cdot y = z = r_3e^{i\\theta_3}$, represented in polar form as a tuple `(r3, θ3)`.\n",
    "\n",
    "* $r_3$ should be non-negative: $r_3 \\geq 0$\n",
    "* $\\theta_3$ should be between $-\\pi$ and $\\pi$: $-\\pi < \\theta_3 \\leq \\pi$\n",
    "* Try to avoid converting the numbers into Cartesian form."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    "\n",
    "Multiplying two complex numbers in polar form can be done efficiently in the following way:\n",
    "\n",
    "$$ z = x \\cdot y = r_{1}e^{\\theta_1 i} \\cdot r_{2}e^{\\theta_2 i} = r_{1}r_{2} \\cdot e^{(\\theta_1 + \\theta_2)i} $$  \n",
    "\n",
    "> Here is the longer approach of converting the numbers to the Cartesian from and doing multiplication in it:  \n",
    "> $$ x = r_{1}e^{i\\theta_1} = r_{1}(\\cos \\theta_1 + i \\sin \\theta_1) $$\n",
    "> $$ y = r_{2}e^{i\\theta_2} = r_{2}(\\cos \\theta_2 + i \\sin \\theta_2) $$\n",
    "> $$ z = x \\cdot y = r_1r_2 \\cdot \\left( \\cos \\theta_1 \\cos \\theta_2 − \\sin \\theta_1 \\sin \\theta_2 + \n",
    "i (\\sin \\theta_1 \\cos \\theta_2 + \\sin \\theta_2 \\cos \\theta_1 ) \\right) $$\n",
    ">\n",
    "> We can simplify this using the following trigonometric identities:\n",
    "> * $\\cos a \\cos b  \\mp \\sin a \\sin b = \\cos(a \\pm b)$\n",
    "> * $\\sin a \\cos b  \\pm \\sin a \\cos b = \\sin(a \\pm b)$\n",
    ">\n",
    "> Finally, this solution gives the same answer as the short solution above:\n",
    ">$$z = r_{1}r_{2}(\\cos(\\theta_1 + \\theta_2) + i \\sin(\\theta_1 + \\theta_2)) = r_{1}r_{2} \\cdot e^{(\\theta_1 + \\theta_2)i} $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def polar_mult(x : Polar, y : Polar) -> Polar:\n",
    "    \n",
    "    (r1, theta1) = x\n",
    "    (r2, theta2) = y\n",
    "    \n",
    "    real = r1 * r2\n",
    "    \n",
    "    angle = theta1 + theta2\n",
    "    \n",
    "    # If the calculated angle is larger then pi, we will subtract 2pi\n",
    "    if (angle > math.pi):\n",
    "        # Reassign the value for angle\n",
    "        angle = angle - 2.0 * math.pi\n",
    "        \n",
    "    # If the calculated angle is smaller then -pi, we will add 2 pi\n",
    "    elif (angle <= -math.pi):\n",
    "        angle = angle + 2.0 * math.pi\n",
    "    \n",
    "    return (real, angle)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 11 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-11:-Polar-multiplication.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 12</span>**: Arbitrary complex exponents.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
    "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
    "\n",
    "**Goal:** Return the result of raising $x$ to the power of $y$: $x^y = (a + bi)^{c + di} = z = g + hi$, represented as a tuple `(g, h)`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution\n",
    " \n",
    "Let's convert the number $x$ to polar form $x = re^{i\\theta}$ and rewrite the complex exponent as follows:\n",
    "\n",
    "$$ x^y = \\left( re^{i\\theta} \\right)^{c + di} = e^{(\\ln(r) + i\\theta)(c + di)} = $$\n",
    "$$ = e^{\\ln(r) \\cdot c \\, + \\, \\ln(r) \\cdot di \\, + \\, i\\theta \\cdot c \\, + \\, (d\\theta)i^2} = \n",
    "e^{\\left(\\ln(r) \\cdot c \\, - \\, d\\theta \\right) \\, + \\, \\left(\\ln(r) \\cdot d \\, + \\, \\theta c\\right)i} $$\n",
    "\n",
    "Finally, this needs to be converted back to Cartesian form using Euler's formula:\n",
    "\n",
    "$$ e^{\\ln(r) \\cdot c - d\\theta} \\cdot (\\cos (\\ln(r) \\cdot d + \\theta c) + i\\sin (\\ln(r) \\cdot d + \\theta c)) $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@exercise\n",
    "def complex_exp_arbitrary(x : Complex, y : Complex) -> Complex:\n",
    "    \n",
    "    (a, b) = x\n",
    "    (c, d) = y\n",
    "\n",
    "    # Convert x to polar form\n",
    "    r = math.sqrt(a ** 2 + b ** 2)\n",
    "    theta = math.atan2(b, a)\n",
    "    \n",
    "    # Special case for r = 0\n",
    "    if (r == 0):\n",
    "        return (0, 0)\n",
    "\n",
    "    lnr = math.log(r)\n",
    "    \n",
    "    exponent = math.exp(lnr * c - d * theta)\n",
    "    \n",
    "    real = exponent * (math.cos(lnr * d + theta * c ))\n",
    "    imaginary = exponent * (math.sin(lnr * d + theta * c))\n",
    "    \n",
    "    return (real, imaginary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to task 12 of the Complex Arithmetic tutorial.](./ComplexArithmetic.ipynb#Exercise-12**:-Arbitrary-complex-exponents.)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
